﻿#region Using's

using System;
using System.Text.RegularExpressions;

using MyUtils;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Test.MyUtils.TestHelp;

#endregion

namespace Test.MyUtils
{
	[TestClass]
	public class TimeSpanArrangere : FixtureMsTest
	{
		static readonly long oneMillisecondTicks = TimeSpan.FromMilliseconds(1).Ticks;

		static readonly TimeSpan firstPartOfMillisecond;
		static readonly TimeSpan secondPartOfMillisecond;

		static TimeSpanArrangere()
		{
			firstPartOfMillisecond = TimeSpan.FromTicks(oneMillisecondTicks / 3);
			secondPartOfMillisecond = TimeSpan.FromTicks(oneMillisecondTicks * 2 / 3);
		}

		static void AssertMatch(string pattern, string actual)
		{
			if (!Regex.IsMatch(actual, pattern))
			{
				throw new Exception();
			}
		}

		[TestMethod]
		public void Should_parse_from_string_with_explicit_default_scale()
		{
			Equal(TimeSpan.FromMilliseconds(7), "7".ToSpan("ms"));
			Equal(TimeSpan.FromSeconds(7) + TimeSpan.FromMilliseconds(77), "7s 77".ToSpan("ms"));
			Equal(TimeSpan.FromSeconds(7) + TimeSpan.FromSeconds(77), "7s 77".ToSpan("s"));
			Equal(TimeSpan.FromMilliseconds(7) + TimeSpan.FromSeconds(77), "7ms 77".ToSpan("s"));
		}

		[TestMethod]
		public void Should_parse_from_string()
		{
			Equal(TimeSpan.FromMilliseconds(777), "777ms".ToSpan("d"));

			Equal(TimeSpan.FromSeconds(77.7), "77,7 s".ToSpan("d"));
			Equal(TimeSpan.FromSeconds(77.7), "77,7 sec".ToSpan("d"));

			Equal(TimeSpan.FromMinutes(77.7), "77,7 min".ToSpan("d"));

			Equal(TimeSpan.FromHours(77.7), "77,7 h".ToSpan("d"));

			Equal(TimeSpan.FromDays(7), "7 d".ToSpan("d"));
			Equal(TimeSpan.FromDays(7), "7 day".ToSpan("d"));
			Equal(TimeSpan.FromDays(7), "7   \t  day".ToSpan("d"));
			Equal(TimeSpan.FromDays(7.3), "7,3    day".ToSpan("d"));
			Equal(TimeSpan.FromDays(7.3), "7.3 d".ToSpan("d"));

			Equal(TimeSpan.FromDays(49), "7 w".ToSpan("d"));
			Equal(TimeSpan.FromDays(365.24 * 7 / 12), "7 month".ToSpan("d"));

			Equal(TimeSpan.FromDays(365.24 * 2), "2 yr".ToSpan("d"));

			Equal(TimeSpan.FromDays(7).Add(TimeSpan.FromHours(3.3).Add(TimeSpan.FromMilliseconds(4))),
			      "7d3,3h 4ms".ToSpan("d"));


			Equal("7.1 d".ToSpan("d"), "7d3,3h 4ms".ToSpan("d").ToSpanString().ToSpan("d"));

			Equal(TimeSpan.FromDays(7).Add(TimeSpan.FromHours(1)), "7   day      1     h".ToSpan("d"));

			Equal(new TimeSpan(1, 2, 3), "1h 2m 3s".ToSpan("d"));
			Equal(new TimeSpan(1, 2, 3), "1h    2m       3s".ToSpan("d"));
			Equal(new TimeSpan(1, 2, 3), "1h2m3s".ToSpan("d"));
		}

		[TestMethod]
		public void should_show_days()
		{
			AssertMatch("1[,.]7 day", TimeSpan.FromDays(1.733).ToSpanString());
			AssertMatch("3[,.]8 days", TimeSpan.FromDays(3.783).ToSpanString());
		}

		[TestMethod]
		public void should_show_hours()
		{
			AssertMatch("13[,.]7 hr", TimeSpan.FromHours(13.733).ToSpanString());
			AssertMatch("13[,.]8 hr", TimeSpan.FromHours(13.783).ToSpanString());
		}

		[TestMethod]
		public void should_show_mins()
		{
			AssertMatch("53[,.]7 min", TimeSpan.FromMinutes(53.733).ToSpanString());
			AssertMatch("53[,.]8 min", TimeSpan.FromMinutes(53.783).ToSpanString());
		}

		[TestMethod]
		public void should_show_ms()
		{
			AssertMatch("950[,.]3 ms", TimeSpan.FromMilliseconds(950).Add(firstPartOfMillisecond).ToSpanString());
			AssertMatch("950[,.]7 ms", TimeSpan.FromMilliseconds(950).Add(secondPartOfMillisecond).ToSpanString());
		}

		[TestMethod]
		public void should_show_sec()
		{
			AssertMatch("53[,.]7 sec", TimeSpan.FromSeconds(53.733).ToSpanString());
			AssertMatch("53[,.]8 sec", TimeSpan.FromSeconds(53.783).ToSpanString());
		}
	}
}